/* Copyright (c) 2025 Beijing Semidrive Technology Corporation
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/** ************************************************************************************************
 * @file     sdrv_FMMU_lld.h                                                                       *
 * @brief    This file contains interface header for FMMU LLD driver, ...                          *
 * @author   Department/Semidrive                                                                  *
 * @date     2024/11/21                                                                            *
 *                                                                                                 *
 **************************************************************************************************/

#ifndef SDRV_FMMU_LLD_H
#define SDRV_FMMU_LLD_H

#include "fmmu_ip.h"
#include "lld_platform.h"


#ifdef __cplusplus
extern "C" {
#endif

/***************************************************************************************************
 *                                 Global Macro definition
 **************************************************************************************************/
#define FMMU_REMAP_SIZE(SizeNum)                (0x1ul << (6 + (SizeNum)))
#define FMMU_EN_NUM                             (16u)
#define FMMU_ADDR_TO_OFF(addr)                  ((addr) >> 6)
#define FMMU_OFF_TO_ADDR(offset)                ((offset) << 6)


#define FMMU_MODULE_ID                  (2055U)
/**
 *  \name PFU Error Codes
 *
 *  Error codes returned by PFU functions
 *  \{
 */
#if defined (CFG_PLATFORM_MCAL)
#define FMMU_NO_ERROR                   (0x00u)
#define FMMU_E_PARAM_POINTER            (0x01u)
#define FMMU_E_PARAM_INVALID            (0x02u)
#define FMMU_E_SRCADDR_INVALID          (0x03u)
#define FMMU_E_DSTADDR_INVALID          (0x04u)
#define FMMU_E_OVER_REGIONNUM           (0x05u)
#define FMMU_E_SRCADDR_OVERLAP          (0x06u)
#define FMMU_E_NOT_ALIGNED_SIZE         (0x07u)
#define FMMU_E_REGION_ENABLED           (0x08u)
#define FMMU_E_REGION_LOCKED            (0x09u)
#define FMMU_E_WRIT_REG_EXCEPTION       (0x0Au)

#elif defined (CFG_PLATFORM_SSDK)
#define FMMU_NO_ERROR                   SDRV_STATUS_OK
#define FMMU_E_PARAM_POINTER            SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_FMMU, 1)
#define FMMU_E_PARAM_INVALID            SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_FMMU, 2)
#define FMMU_E_SRCADDR_INVALID          SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_FMMU, 3)
#define FMMU_E_DSTADDR_INVALID          SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_FMMU, 4)
#define FMMU_E_OVER_REGIONNUM           SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_FMMU, 5)
#define FMMU_E_SRCADDR_OVERLAP          SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_FMMU, 6)
#define FMMU_E_NOT_ALIGNED_SIZE         SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_FMMU, 7)
#define FMMU_E_REGION_ENABLED           SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_FMMU, 8)
#define FMMU_E_REGION_LOCKED            SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_FMMU, 9)
#define FMMU_E_WRIT_REG_EXCEPTION       SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_FMMU, 10)

#else
#error "Undefined macros CFG_PLATFORM_MCFORM_SSDK"
#endif /** #if defined (CFG_PLATFORM_MCAL) */
/** \} */


typedef enum Fmmu_RemapSize {
    FMMU_SIZE_64BYTE = 0U,  //0x40
    FMMU_SIZE_128BYTE,      //0x80
    FMMU_SIZE_256BYTE,      //0x100
    FMMU_SIZE_512BYTE,      //0x200
    FMMU_SIZE_1KB,          //0x400
    FMMU_SIZE_2KB,          //0x800
    FMMU_SIZE_4KB,          //0x1000
    FMMU_SIZE_8KB,          //0x2000
    FMMU_SIZE_16KB,         //0x4000
    FMMU_SIZE_32KB,         //0x8000
    FMMU_SIZE_64KB,         //0x1_0000
    FMMU_SIZE_128KB,        //0x2_0000
    FMMU_SIZE_256KB,        //0x4_0000
    FMMU_SIZE_512KB,        //0x8_0000
    FMMU_SIZE_1MB,          //0x10_0000
    FMMU_SIZE_2MB,          //0x20_0000
    FMMU_SIZE_MAX
}Fmmu_RemapSize_t;

typedef enum {
    FMMU_REGION_DIS = 0U,
    FMMU_REGION_EN,
    FMMU_REGION_EN_ERROR
} Fmmu_RegionEn_t;

typedef enum {
    FMMU_LOCK_DIS = 0U,
    FMMU_LOCK_EN,
    FMMU_LOCK_ERROR
} Fmmu_RegionLatch_t;



/***************************************************************************************************
 *                                  Global Types definition                                        *
 **************************************************************************************************/
typedef struct {
    Fmmu_Type_t type;
    uint8_t regionId;
    Fmmu_RemapSize_t remapSize;
    uint32_t srcAddr;
    uint32_t dstAddr;
} Fmmu_RegionConfigType;

typedef struct {
    Fmmu_RegionConfigType regionConfig;
    Fmmu_RegionEn_t en;
    Fmmu_RegionLatch_t lock;
} Fmmu_ConfigType;


/***************************************************************************************************
 *                                  Global Function Declarations                                   *
 **************************************************************************************************/
lld_status_t Fmmu_Init(Fmmu_Core_t core, const Fmmu_ConfigType * config, uint32_t RegionNum);
lld_status_t Fmmu_RegionEnable(Fmmu_Core_t core, Fmmu_Type_t RemapType, uint32_t RegionId, Fmmu_RegionEn_t En);
lld_status_t Fmmu_RegionLock(Fmmu_Core_t core, Fmmu_Type_t RemapType, uint32_t RegionId);
lld_status_t Fmmu_RegionConfig(Fmmu_Core_t core, const Fmmu_RegionConfigType * config);
Fmmu_RegionEn_t Fmmu_GetRegionEnStatus(Fmmu_Core_t core, Fmmu_Type_t RemapType, uint32_t RegionId);
Fmmu_RegionLatch_t Fmmu_GetRegionLockStatus(Fmmu_Core_t core, Fmmu_Type_t RemapType, uint32_t RegionId);
lld_status_t Fmmu_GetRegionConfig(Fmmu_Core_t core, Fmmu_Type_t remapType, uint32_t regionId, Fmmu_RegionConfigType * config);
uint32_t Fmmu_GetRemapDstAddr(Fmmu_Core_t core, uint32_t SrcAddr, uint32_t Size);


#ifdef __cplusplus
}
#endif
#endif /* SDRV_FMMU_LLD_H */
